home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / gfx / 3d / Skulpt_src.lha / sKulpt-src / MenuWProc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-05  |  53.5 KB  |  1,356 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16. #include <d3dx.h>
  17.  
  18. // Includes utilitaires D3D
  19. #include "d3dmath.h"
  20. #include "d3dutil.h"
  21. #include "D3DEnum.h"
  22.  
  23. // Ids Resources
  24. #include "resource.h"
  25.  
  26. // Constantes
  27. #include "const.h"
  28.  
  29. // Types
  30. #include "types.h"
  31.  
  32. // Variables globales projet
  33. #include "vars.h"
  34.  
  35. // Prototypes fonctions autres modules
  36. #include "proto.h"
  37.  
  38. // Macros
  39. #include "macros.h"
  40.  
  41. // Sortir un résumé de la scène dans la fenêtre de trace
  42. void vDescribe(void)
  43. {
  44.     int iCnt,
  45.         iVertices = 0,
  46.         iSelectedVertices = 0,
  47.         iHiddenVertices = 0,
  48.         iTriangles = 0,
  49.         iHiddenTriangles = 0,
  50.         iEdges = 0,
  51.         iHiddenEdges = 0,
  52.         iLamps = 0,
  53.         iSelectedLamps = 0,
  54.         iLitLamps = 0,
  55.         iObjects = 0,
  56.         iSelectedObjects = 0,
  57.         iMaterials = 0,
  58.         iHiddenObjects = 0,
  59.         iTextures = 0,
  60.         iTexBuf = 0;
  61.  
  62.     vTrace("*** Résumé scène courante :");
  63.  
  64.     // Compter les points
  65.     for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  66.         if (Vertices[iCnt].bEnabled)
  67.         {
  68.             iVertices++;
  69.             if (bIsVertexSelected(iCnt)) iSelectedVertices++;
  70.             if (Vertices[iCnt].bHidden) iHiddenVertices++;
  71.         }
  72.  
  73.     // Compter les lampes
  74.     for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  75.         if (Lampes[iCnt].bEnabled)
  76.         {
  77.             iLamps++;
  78.             if (Lampes[iCnt].bSelected) iSelectedLamps++;
  79.             if (Lampes[iCnt].bLit) iLitLamps++;
  80.         }
  81.  
  82.     // Compter les objets
  83.     for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  84.         if (Objects[iCnt].bEnabled)
  85.         {
  86.             iObjects++;
  87.             if (Objects[iCnt].bSelected) iSelectedObjects++;
  88.             if (Objects[iCnt].bHidden) iHiddenObjects++;
  89.         }
  90.  
  91.     // Compter les arêtes
  92.     for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
  93.         if (Edges[iCnt].bEnabled)
  94.         {
  95.             iEdges++;
  96.             if (Edges[iCnt].bHidden) iHiddenEdges++;
  97.         }
  98.  
  99.     // Compter les triangles
  100.     for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  101.         if (Triangles[iCnt].bEnabled)
  102.         {
  103.             iTriangles++;
  104.             if (Triangles[iCnt].bHidden) iHiddenTriangles++;
  105.         }
  106.  
  107.     // Compter les matériaux
  108.     for (iCnt = 0 ; iCnt <= iMtrlLastUsed ; iCnt++)
  109.         if (Materials[iCnt].bEnabled)
  110.             iMaterials++;
  111.  
  112.     // Compter les textures
  113.     for (iCnt = 0 ; iCnt < XDC_NUMTEX ; iCnt++)
  114.         if (Textures[iCnt].hTexMap)
  115.         {
  116.             iTextures++;
  117.             iTexBuf += 4 * Textures[iCnt].iHeight * Textures[iCnt].iWidth;
  118.         }
  119.  
  120.  
  121.     vTrace("Taille (k) : vert %d, edges %d, triangles %d, objets %d, matériaux %d, textures %d, total %d.", sizeof(Vertices) / 1024, sizeof(Edges) / 1024, sizeof(Triangles) / 1024, sizeof(Objects) / 1024, sizeof(Materials) / 1024, sizeof(Textures) / 1024, (sizeof(Vertices) + sizeof(Edges) + sizeof(Triangles) + sizeof(Objects) + sizeof(Materials) + sizeof(Textures)) / 1024);
  122.     if (iVertices) vTrace("Points : %d (%d sélectionnés, %d cachés). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iVertices, iSelectedVertices, iHiddenVertices, iVertLastUsed, iVertFirstAvailable, 100 * ((iVertLastUsed + 1) - iVertices) / iVertices);
  123.     if (iEdges) vTrace("Arêtes : %d (%d cachées). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iEdges, iHiddenEdges, iEdgeLastUsed, iEdgeFirstAvailable, 100 * ((iEdgeLastUsed + 1) - iEdges) / iEdges);
  124.     if (iTriangles) vTrace("Triangles : %d (%d cachés). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iTriangles, iHiddenTriangles, iTriaLastUsed, iTriaFirstAvailable, 100 * ((iTriaLastUsed + 1) - iTriangles) / iTriangles);
  125.     if (iObjects) vTrace("Objets : %d (%d sélectionnés, %d cachés). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iObjects, iSelectedObjects, iHiddenObjects, iObjtLastUsed, iObjtFirstAvailable, 100 * ((iObjtLastUsed + 1) - iObjects) / iObjects);
  126.     if (iLamps) vTrace("Lampes : %d (%d sélectionnées, %d allumées). Dernière utilisée : %d, premier dispo : %d (frag : %d%%)", iLamps, iSelectedLamps, iLitLamps, iLampLastUsed, iLampFirstAvailable, 100 * ((iLampLastUsed + 1) - iLamps) / iLamps);
  127.     if (iMaterials) vTrace("Matériaux : %d. Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iMaterials, iMtrlLastUsed, iMtrlFirstAvailable, 100 * ((iMtrlLastUsed + 1) - iMaterials) / iMaterials);
  128.     if (iTextures) vTrace("Textures : %d k de buffers en %d textures en mémoire", iTexBuf / 1024, iTextures);
  129. }
  130.  
  131. // Redimensionner la triview
  132. void vRemakeTriview(LPARAM lParam)
  133. {
  134.     int iScreenWidth, iScreenHeight;
  135. #ifndef _AMIGA_
  136.     HDC hdcScreen;
  137.  
  138.     if (!lParam)
  139.     {
  140.         hdcScreen = GetDC(NULL);
  141.         iScreenWidth = GetDeviceCaps(hdcScreen, HORZRES);
  142.         iScreenHeight = GetDeviceCaps(hdcScreen, VERTRES);
  143.     }
  144.     else
  145.     {
  146.         iScreenWidth = LOWORD(lParam);
  147.         iScreenHeight = HIWORD(lParam);
  148.     }
  149.  
  150.     vTrace("Réorganisation des fenêtres (écran %d x %d)", iScreenWidth, iScreenHeight);
  151.  
  152.     MoveWindow(hWndMenu, 0, 0, iScreenWidth, iScreenHeight / 9, TRUE);
  153.     MoveWindow(hWndPersp, iScreenWidth/2, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  154.     MoveWindow(hWndTop, 0, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  155.     MoveWindow(hWndFace, 0, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  156.     MoveWindow(hWndRight, iScreenWidth/2, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  157.  
  158.     if (!lParam) ReleaseDC(NULL, hdcScreen);
  159. #else
  160.     iScreenWidth = hInst -> Width;
  161.     iScreenHeight = hInst -> Height;
  162.  
  163.     vTrace("Réorganisation des fenêtres (écran %d x %d)", iScreenWidth, iScreenHeight);
  164.  
  165.     ChangeWindowBox(hWndMenu, 0, 0, iScreenWidth, iScreenHeight / 9);
  166.     ChangeWindowBox(hWndPersp, iScreenWidth/2, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9);
  167.     ChangeWindowBox(hWndTop, 0, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9);
  168.     ChangeWindowBox(hWndFace, 0, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9);
  169.     ChangeWindowBox(hWndRight, iScreenWidth/2, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9);
  170.  
  171.     // Laisser à Intuition le temps de flusher ses buffers de rendering
  172.     Delay(5); // * 20 ms soit 100 ms
  173. #endif
  174. }
  175.  
  176. // Mettre à jour les menus en fonction des variables de mode courant
  177. void vUpdateMenu(void)
  178. {
  179.     HMENU hMenu = GetMenu(hWndMenu);
  180.     CheckMenuItem(hMenu, ID_EDITION_GRILLE, MF_BYCOMMAND | (bGrid ? MF_CHECKED : MF_UNCHECKED));
  181.     CheckMenuItem(hMenu, ID_EDITION_COORDONNES, MF_BYCOMMAND | (bCoords ? MF_CHECKED : MF_UNCHECKED));
  182.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_POINT, MF_BYCOMMAND | (dFillMode == D3DFILL_POINT ? MF_CHECKED : MF_UNCHECKED));
  183.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_FILDEFERF, MF_BYCOMMAND | (dFillMode == D3DFILL_WIREFRAME ? MF_CHECKED : MF_UNCHECKED));
  184.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_FACETTES, MF_BYCOMMAND | (dFillMode == D3DFILL_SOLID ? MF_CHECKED : MF_UNCHECKED));
  185.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_ZBUFFER, (dZBuf == D3DZB_TRUE ? MF_CHECKED : MF_UNCHECKED));
  186.     CheckMenuItem(hMenu, ID_OUTILS_AUCUN, MF_BYCOMMAND | MF_UNCHECKED);
  187.     CheckMenuItem(hMenu, ID_OUTILS_SLECTEUR, MF_BYCOMMAND | MF_UNCHECKED);
  188.     CheckMenuItem(hMenu, ID_OUTILS_DSLECTEUR, MF_BYCOMMAND | MF_UNCHECKED);
  189.     CheckMenuItem(hMenu, ID_OUTILS_AIMANT, MF_BYCOMMAND | MF_UNCHECKED);
  190.     CheckMenuItem(hMenu, ID_OUTILS_COURBE, MF_BYCOMMAND | MF_UNCHECKED);
  191.     CheckMenuItem(hMenu, ID_OUTILS_EXTRUDEUR, MF_BYCOMMAND | MF_UNCHECKED);
  192.     CheckMenuItem(hMenu, ID_OUTILS_PINCE, MF_BYCOMMAND | MF_UNCHECKED);
  193.  
  194.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE, MF_BYCOMMAND | MF_UNCHECKED);
  195.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW, MF_BYCOMMAND | MF_UNCHECKED);
  196.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW, MF_BYCOMMAND | MF_UNCHECKED);
  197.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_ANTIALIAS, (bAntialias ? MF_CHECKED : MF_UNCHECKED));
  198.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_TRANSPARENCEALPHABLENDING, (bAlpha ? MF_CHECKED : MF_UNCHECKED));
  199.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_ECLAIRAGESPCULAIRE, (bSpecular ? MF_CHECKED : MF_UNCHECKED));
  200.     CheckMenuItem(hMenu, ID_ENVIRONNEMENT_MODE_VUE3DDSACTIVE, (bActive ? MF_UNCHECKED : MF_CHECKED));
  201.     CheckMenuItem(hMenu, ID_ENVIRONNEMENT_MODE_LIGHTINGCOMPLET, (bLightFull ? MF_CHECKED : MF_UNCHECKED));
  202.     switch(dCull)
  203.     {
  204.         case D3DCULL_NONE:
  205.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE, MF_BYCOMMAND | MF_CHECKED);
  206.             break;
  207.  
  208.         case D3DCULL_CW:
  209.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW, MF_BYCOMMAND | MF_CHECKED);
  210.             break;
  211.  
  212.         case D3DCULL_CCW:
  213.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW, MF_BYCOMMAND | MF_CHECKED);
  214.             break;
  215.     }
  216.  
  217.     switch(cTool)
  218.     {
  219.         case XDC_TOOL_NONE:
  220.             CheckMenuItem(hMenu, ID_OUTILS_AUCUN, MF_BYCOMMAND | MF_CHECKED);
  221.             break;
  222.  
  223.         case XDC_TOOL_SELECT:
  224.             CheckMenuItem(hMenu, ID_OUTILS_SLECTEUR, MF_BYCOMMAND | MF_CHECKED);
  225.             break;
  226.  
  227.         case XDC_TOOL_UNSELECT:
  228.             CheckMenuItem(hMenu, ID_OUTILS_DSLECTEUR, MF_BYCOMMAND | MF_CHECKED);
  229.             break;
  230.  
  231.         case XDC_TOOL_MAGNET:
  232.             CheckMenuItem(hMenu, ID_OUTILS_AIMANT, MF_BYCOMMAND | MF_CHECKED);
  233.             break;
  234.  
  235.         case XDC_TOOL_CURVE:
  236.             CheckMenuItem(hMenu, ID_OUTILS_COURBE, MF_BYCOMMAND | MF_CHECKED);
  237.             break;
  238.  
  239.         case XDC_TOOL_EXTRUDE:
  240.             CheckMenuItem(hMenu, ID_OUTILS_EXTRUDEUR, MF_BYCOMMAND | MF_CHECKED);
  241.             break;
  242.  
  243.         case XDC_TOOL_GRAB:
  244.             CheckMenuItem(hMenu, ID_OUTILS_PINCE, MF_BYCOMMAND | MF_CHECKED);
  245.             break;
  246.     }
  247. }
  248.  
  249.  
  250. // Gérer les messages de la fenêtre menu / trace
  251. LRESULT CALLBACK lrMenuWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  252. {
  253.     static int iCurveStartVertex, iCurveLastVertex;
  254.     int wmId, wmEvent, iCnt, jCnt;
  255.     float fDist;
  256.     SMALLBOOL bShouldRedraw, bSelectState;
  257.     char cKey;
  258. #ifndef _AMIGA_
  259.     DWORD dwTime;
  260. #endif
  261.     D3DCOLORVALUE   dcvDiffuse  = {1.f, 1.f, 1.f, 0.f},
  262.                     dcvSpecular = {1.f, 1.f, 1.f, 0.f},
  263.                     dcvAmbient  = {1.f, 1.f, 1.f, 0.f};
  264.  
  265.     // vTrace("Message fenêtre menu type %d, wP %d, lP %d", uMsg, wParam, lParam);
  266.  
  267.     switch( uMsg )
  268.     {
  269.     case WM_CREATE :
  270.         // Mettre à jour les toggle flags des menus en fonction de l'état des variables de mode
  271.         vUpdateMenu();
  272.         break;
  273.  
  274.     case WM_COMMAND :
  275.          wmId    = LOWORD(wParam);
  276.          wmEvent = HIWORD(wParam);
  277.  
  278.          switch (wmId) {
  279.  
  280.             //////////////////////////////////// M E N U  P R O J E T ///////////////
  281.             case ID_PROJET_CHARGER_SCNESCULPT :
  282.                 // Charger la scène Sculpt
  283.                 vLoadSculpt();
  284.  
  285.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  286.                 vSetD3DState();
  287.                 goto _RedrawAll;
  288.  
  289.             case ID_PROJET_CHARGER_SCNESKULPTD3DW3D :
  290.                 // Charger la scène
  291.                 vLoadBin();
  292.  
  293.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  294.                 vSetD3DState();
  295.                 goto _RedrawAll;
  296.  
  297.             case ID_PROJET_CHARGER_SCNEDIRECTX :
  298.                 // Charger la scène
  299.                 vLoadDirectX();
  300.  
  301.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  302.                 vSetD3DState();
  303.                 goto _RedrawAll;
  304.  
  305.             case ID_PROJET_SAUVER_SCNESCULPT :
  306.                 // Sauver la scène Sculpt
  307.                 vSaveSculpt();
  308.                 break;
  309.  
  310.             case ID_PROJET_SAUVER_SCNESKULPTD3DW3D :
  311.                 // Sauver la scène
  312.                 vSaveBin();
  313.                 break;
  314.  
  315.             case ID_PROJET_SAUVER_SCNEDIRECTX :
  316.                 // Sauver la scène
  317.                 vSaveDirectX();
  318.                 break;
  319.  
  320.             case ID_PROJET_APROPOS:
  321.                 vLogo();
  322.                 break;
  323.  
  324.             case ID_PROJET_RSUM :
  325.                 vDescribe();
  326.                 break;
  327.  
  328.             case ID_PROJET_QUITTER:
  329.                DestroyWindow (hWnd);
  330.                break;
  331.  
  332.             //////////////////////////////////// M E N U  E D I T I O N ///////////////
  333.             case ID_EDITION_SLECTIONNER_TOUT:
  334.             case ID_EDITION_DSLECTIONNER_TOUT:
  335.                 // (Dé)Sélectionner les sommets
  336.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  337.                 {
  338.                     if (Vertices[iCnt].bEnabled == FALSE) continue;
  339.                     if (Vertices[iCnt].bHidden == TRUE) continue;
  340.  
  341.                     Vertices[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  342.                 }
  343.  
  344.                 // (Dé)Sélectionner les objets D3D
  345.                 for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  346.                 {
  347.                     if (Objects[iCnt].bEnabled == FALSE) continue;
  348.                     if (Objects[iCnt].bHidden == TRUE) continue;
  349.  
  350.                     Objects[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  351.                 }
  352.  
  353.                 // Ne pas sélectionner les lampes
  354.                 if (wmId == ID_EDITION_SLECTIONNER_TOUT) goto _SelectDone;
  355.  
  356.                 // Désélectionner les lampes
  357.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  358.                 {
  359.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  360.  
  361.                     Lampes[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  362.                 }
  363. _SelectDone:
  364.                 vForce2DRefresh(XDC_MODE_COMPLET);
  365.                 break;
  366.  
  367.             case ID_EDITION_SLECTIONNER_NOEUDSCONNEXES:
  368.                 vCollect();
  369.                 vPropagateSelection();
  370.                 vForce2DRefresh(XDC_MODE_COMPLET);
  371.                 break;
  372.  
  373.             case ID_EDITION_SLECTIONNER_NOEUDINDIQU:
  374.             case ID_EDITION_DSLECTIONNER_NOEUDINDIQU:
  375.                 // Attention : en mode menu, ce traitement sélectionne le noeud indiqué.
  376.                 // Il peut aussi être appelé par 2nwndproc.c en mode dé/sélecteur, avec lParam != 0.
  377.                 // Il faut alors dé/sélectionner tous les points dans la zone de tolérance et pas seulement le
  378.                 // premier
  379.  
  380.                 // Chercher le premier point dans la zone curseur
  381.                 iCnt = iFindVertex(Cursor1, -1);
  382.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  383.  
  384.                 // Si on n'a pas trouvé alors on cherche une lampe
  385.                 if (iCnt == -1)
  386.                 {
  387.                     PostMessage(hWnd, WM_COMMAND, ID_EDITION_SLECTIONNER_LAMPEINDIQUE, lParam);
  388.                     break;
  389.                 }
  390.  
  391.                 switch(lParam)
  392.                 {
  393.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_NOEUDINDIQU ? TRUE : FALSE); break;
  394.                 case XDC_SINGLETOGGLE: bSelectState = !Vertices[iCnt].bSelected; break;
  395.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  396.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  397.                 }
  398.  
  399.                 while (iCnt != -1)
  400.                 {
  401.                     if (Vertices[iCnt].bSelected != bSelectState)
  402.                     {
  403.                         Vertices[iCnt].bSelected = bSelectState;
  404.                         PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  405.                         PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  406.                         PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  407.                         bShouldRedraw = TRUE;
  408.                     }
  409.  
  410.                     // Trouver le point suivant si on est en mode outil sélecteur (lParam == XDC_SELECTALL)
  411.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  412.                         iCnt = iFindVertex(Cursor1, iCnt);
  413.                     else
  414.                         iCnt = -1;
  415.                 }
  416.  
  417.                 // Redessiner partiellement les vues 2D si des points ont été traités
  418.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_PARTIEL);
  419.                 break;
  420.  
  421.             case ID_EDITION_SLECTIONNER_LAMPEINDIQUE:
  422.             case ID_EDITION_DSLECTIONNER_LAMPEINDIQUE:
  423.                 // Chercher la lampe dans la zone curseur
  424.                 iCnt = iFindLamp(Cursor1, -1);
  425.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  426.  
  427.                 // Si on n'a pas trouvé alors on cherche un objet D3D
  428.                 if (iCnt == -1)
  429.                 {
  430.                     PostMessage(hWnd, WM_COMMAND, ID_EDITION_SLECTIONNER_OBJETD3DINDIQU, lParam);
  431.                     break;
  432.                 }
  433.  
  434.                 switch(lParam)
  435.                 {
  436.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_LAMPEINDIQUE ? TRUE : FALSE); break;
  437.                 case XDC_SINGLETOGGLE: bSelectState = !Lampes[iCnt].bSelected; break;
  438.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  439.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  440.                 }
  441.  
  442.                 while (iCnt != -1)
  443.                 {
  444.                     if (Lampes[iCnt].bSelected != bSelectState)
  445.                     {
  446.                         Lampes[iCnt].bSelected = bSelectState;
  447.                         bShouldRedraw = TRUE;
  448.                     }
  449.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  450.                         iCnt = iFindLamp(Cursor1, iCnt);
  451.                     else
  452.                         iCnt = -1;
  453.                 }
  454.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  455.                 break;
  456.  
  457.             case ID_EDITION_SLECTIONNER_TOUTESLESLAMPES:
  458.             case ID_EDITION_DSLECTIONNER_TOUTESLESLAMPES:
  459.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  460.                     if (Lampes[iCnt].bEnabled)
  461.                         Lampes[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUTESLESLAMPES ? TRUE : FALSE);
  462.                 vForce2DRefresh(XDC_MODE_COMPLET);
  463.                 break;
  464.  
  465.             case ID_EDITION_SLECTIONNER_OBJETD3DINDIQU:
  466.             case ID_EDITION_DSLECTIONNER_OBJETD3DINDIQU:
  467.                 // Chercher le premier point dans la zone curseur
  468.                 iCnt = iFindD3DObject(Cursor1, -1);
  469.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  470.  
  471.                 if (iCnt == -1) break;
  472.  
  473.                 switch(lParam)
  474.                 {
  475.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_OBJETD3DINDIQU ? TRUE : FALSE); break;
  476.                 case XDC_SINGLETOGGLE: bSelectState = !Objects[iCnt].bSelected; break;
  477.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  478.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  479.                 }
  480.  
  481.                 while (iCnt != -1)
  482.                 {
  483.                     if (Objects[iCnt].bSelected != bSelectState)
  484.                     {
  485.                         Objects[iCnt].bSelected = bSelectState;
  486.                         bShouldRedraw = TRUE;
  487.                     }
  488.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  489.                         iCnt = iFindD3DObject(Cursor1, iCnt);
  490.                     else
  491.                         iCnt = -1;
  492.                 }
  493.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  494.                 break;
  495.  
  496.             case ID_EDITION_SLECTIONNER_INVERSERLASLECTION:
  497.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  498.                     if (Vertices[iCnt].bEnabled)
  499.                         Vertices[iCnt].bSelected = (Vertices[iCnt].bSelected ? FALSE : TRUE);
  500.                 for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  501.                     if (Objects[iCnt].bEnabled)
  502.                         Objects[iCnt].bSelected = (Objects[iCnt].bSelected ? FALSE : TRUE);
  503.                 vForce2DRefresh(XDC_MODE_COMPLET);
  504.                 break;
  505.  
  506.             case ID_EDITION_EFFACER_TOUT :
  507.                 vDeleteObjects();
  508.                 goto _RedrawAll;
  509.  
  510.             case ID_EDITION_EFFACER_NOEUDINDIQU:
  511.                 iCnt = iFindVertex(Cursor1, -1);
  512.                 if (iCnt != -1)
  513.                 {
  514.                     if (bDeleteVertex(iCnt))
  515.                         goto _RedrawAll;
  516.                 }
  517.                 else
  518.                     vTrace("*** E0010 : Pas de noeud à proximité du curseur principal");
  519.                 break;
  520.  
  521.             case ID_EDITION_EFFACER_NOAUDSSLECTIONNS:
  522.                 bShouldRedraw = FALSE;
  523.  
  524.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  525.                     if (bIsVertexSelected(iCnt))
  526.                         bShouldRedraw |= bDeleteVertex(iCnt);
  527.                 
  528.                 if (bShouldRedraw)
  529.                     goto _RedrawAll;
  530.                 break;
  531.  
  532.             case ID_EDITION_EFFACER_ARTESSLECTIONNES:
  533.                 bShouldRedraw = FALSE;
  534.                 for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
  535.                 {
  536.                     if (Edges[iCnt].bEnabled == FALSE) continue;
  537.  
  538.                     if (
  539.                             (Vertices[Edges[iCnt].iSommets[0]].bSelected)
  540.                          && (Vertices[Edges[iCnt].iSommets[1]].bSelected)
  541.                        )
  542.                     {
  543.                        bDeleteEdge(iCnt);
  544.                        bShouldRedraw = TRUE;
  545.                     }
  546.                 }
  547.  
  548.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  549.                 break;
  550.  
  551.             case ID_EDITION_EFFACER_TRIANGLESSLECTIONNS:
  552.                 bShouldRedraw = FALSE;
  553.                 for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  554.                 {
  555.                     if (Triangles[iCnt].bEnabled == FALSE) continue;
  556.  
  557.                     if (bIsTriangleSelected(iCnt))
  558.                     {
  559.                        bDeleteTriangle(iCnt);
  560.                        bShouldRedraw = TRUE;
  561.                     }
  562.                 }
  563.  
  564.                 if (bShouldRedraw) goto _RedrawAll;
  565.                 break;
  566.  
  567.             case ID_EDITION_EFFACER_LAMPEINDIQUE:
  568.                 iCnt = iFindLamp(Cursor1, -1);
  569.                 if (iCnt != -1)
  570.                 {
  571.                     if (bDeleteLamp(iCnt))
  572.                         goto _RedrawAll;
  573.                 }
  574.                 else
  575.                     vTrace("*** E0011 : Pas de lampe à proximité du curseur principal");
  576.                 break;
  577.  
  578.             case ID_EDITION_EFFACER_LAMPESSLECTIONNES:
  579.                 bShouldRedraw = FALSE;
  580.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  581.                 {
  582.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  583.  
  584.                     if (Lampes[iCnt].bSelected)
  585.                     {
  586.                         bDeleteLamp(iCnt);
  587.                         bShouldRedraw = TRUE;
  588.                     }
  589.                 }
  590.  
  591.                 if (bShouldRedraw) goto _RedrawAll;
  592.                 break;
  593.  
  594.             case ID_EDITION_EFFACER_TOUTESLESLAMPES:
  595.                 bShouldRedraw = FALSE;
  596.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  597.                 {
  598.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  599.                     bDeleteLamp(iCnt);
  600.                     bShouldRedraw = TRUE;
  601.                 }
  602.  
  603.                 if (bShouldRedraw) goto _RedrawAll;
  604.                 break;
  605.  
  606.             case ID_EDITION_MODIFIER_MATRIAUX :
  607.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_MATERIAL), hWnd, bMtrlDlgProc);
  608.                 break;
  609.  
  610.             case ID_EDITION_MODIFIER_FACETTES :
  611.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_FACE), hWnd, bFaceDlgProc);
  612.                 break;
  613.  
  614.             case ID_EDITION_MODIFIER_LAMPES :
  615.                 if (iLampLastUsed < 0)
  616.                     vTrace("*** E0000 : il n'existe aucune lampe");
  617.                 else
  618.                     DialogBox(hInst, MAKEINTRESOURCE(IDD_LAMP), hWnd, bLampDlgProc);
  619.                 break;
  620.  
  621.             case ID_EDITION_TRANSFORMER_AGRANDIRRDUIRE:
  622.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_EXPAND), hWnd, bExpandDlgProc);
  623.                 break;
  624.  
  625.             case ID_EDITION_TRANSFORMER_REMPLIR:
  626.                 fill();
  627.                 goto _RedrawAll;
  628.  
  629.             case ID_EDITION_TRANSFORMER_SUBDIVISER:
  630.                 {
  631.                     int iTriNum = iTriaLastUsed;
  632.                     SMALLBOOL *bSubdiv = (SMALLBOOL *) malloc((iTriNum + 1) * sizeof(SMALLBOOL));
  633.                     if (!bSubdiv) break;
  634.                     ZeroMemory(bSubdiv, (iTriNum + 1) * sizeof(SMALLBOOL));
  635.  
  636.                     for (iCnt = 0 ; iCnt <= iTriNum ; iCnt++)
  637.                     {
  638.                         if (Triangles[iCnt].bEnabled == FALSE) continue;
  639.                         bSubdiv[iCnt] = bIsTriangleSelected(iCnt);
  640.                     }
  641.  
  642.                     bShouldRedraw = FALSE;
  643.                     for (iCnt = 0 ; iCnt <= iTriNum ; iCnt++)
  644.                         if (bSubdiv[iCnt])
  645.                         {
  646.                             bSubdivideTriangle(iCnt);
  647.                             bShouldRedraw = TRUE;
  648.                         }
  649.  
  650.                     free(bSubdiv);
  651.  
  652.                     if (bShouldRedraw) goto _RedrawAll;
  653.                 }
  654.                 break;
  655.  
  656.             case ID_EDITION_TRANSFORMER_RPLIQUERSURHLICE:
  657.                 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELIX), hWnd, bHelixDlgProc, NULL);
  658.                 break;
  659.  
  660. #ifndef _AMIGA_
  661.             case ID_EDITION_TRANSFORMER_LISSERLESNOEUDSSLECTIONNS:
  662.             case ID_EDITION_TRANSFORMER_DLISSERLESNOEUDSSLECTIONNS:
  663.                 bSelectState = (wmId == ID_EDITION_TRANSFORMER_LISSERLESNOEUDSSLECTIONNS);
  664.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  665.                 {
  666.                     if (Vertices[iCnt].bEnabled == FALSE) continue;
  667.                     if (Vertices[iCnt].bSelected == FALSE) continue;
  668.                     if (Vertices[iCnt].bSmooth == bSelectState) continue;
  669.  
  670.                     Vertices[iCnt].bSmooth = bSelectState;
  671.                 }
  672.                 for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  673.                     if (
  674.                             (Vertices[Triangles[iCnt].iSommets[0]].bSelected)
  675.                          || (Vertices[Triangles[iCnt].iSommets[1]].bSelected)
  676.                          || (Vertices[Triangles[iCnt].iSommets[2]].bSelected)
  677.                        )
  678.                         bUpdateD3DTri(iCnt);
  679.                 goto _RedrawAll;
  680. #endif
  681.  
  682.             case ID_EDITION_TRANSFORMER_CACHERLESNOEUDSSLECTIONNS:
  683.                 vHideSelection();
  684.                 goto _RedrawAll;
  685.  
  686.             case ID_EDITION_TRANSFORMER_RVLERLESNOEUDSCACHS:
  687.                 vRevealHidden();
  688. _RedrawAll:
  689.                 // Tout retracer
  690.                 vForce2DRefresh(XDC_MODE_COMPLET);
  691.                 vForce3DRefresh(XDC_MODE_COMPLET);
  692.                 break;
  693.  
  694.             case ID_EDITION_TRANSFORMER_MULTIVIEW:
  695.                 vRemakeTriview(NULL);
  696.                 break;
  697.  
  698.             case ID_EDITION_AJOUTER_UNCLNE:
  699.                 cTool = XDC_TOOL_GRAB;
  700.                 bCloneSelection(D3DVECTOR(0.f, 0.f, 0.f), XDC_MODE_CLONE);
  701.                 vUpdateMenu();
  702.                 vForce2DRefresh(XDC_MODE_COMPLET);
  703.                 break;
  704.             
  705.             case ID_EDITION_AJOUTER_POINT:
  706.                 iCnt = iMakeVertex(Cursor1, XDC_ALLOWSAME);
  707.                 if (cTool == XDC_TOOL_CURVE)
  708.                 {
  709.                     // Si le vertex n'est pas le premier de la courbe, tracer l'arête et redessiner en mode complet
  710.                     if (iCurveLastVertex != -1)
  711.                     {
  712.                         iMakeEdge(iCurveLastVertex, iCnt);
  713.                         vForce2DRefresh(XDC_MODE_COMPLET);
  714.                     }
  715.                     else // Sinon redessiner en mode partiel après avoir forcé le dessin du point, et mémoriser l'indice du point pour pouvoir refermer la courbe sur 'f'
  716.                     {
  717.                         iCurveStartVertex = iCnt;
  718.                         PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  719.                         PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  720.                         PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  721.                         vForce2DRefresh(XDC_MODE_PARTIEL);
  722.                     }
  723.  
  724.                     iCurveLastVertex = iCnt;
  725.                 }
  726.                 else
  727.                 {
  728.                     // Forcer le dessin du point et rafraichir 2D en mode partiel
  729.                     PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  730.                     PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  731.                     PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  732.                     vForce2DRefresh(XDC_MODE_PARTIEL);
  733.                 }
  734.                 break;
  735.  
  736.             case ID_EDITION_AJOUTER_ARTEOUTRIANGLE:
  737.                 {
  738.                     int iPoint[3], iPoints = 0;
  739.  
  740.                     // Compter et mémoriser les points sélectionnés (jusqu'à 3)
  741.                     for (int iVertex = 0 ; iVertex <= iVertLastUsed ; iVertex++)
  742.                         if (bIsVertexSelected(iVertex))
  743.                         {
  744.                             if (iPoints < 3) iPoint[iPoints] = iVertex;
  745.                             iPoints++;
  746.                         }
  747.  
  748.                     // - soit il existe exactement 2 points sélectionnés et on fait une arête avec
  749.                     //   si elle n'existe pas déjà
  750.                     //   (on ne transforme pas 3 points reliés par 3 arêtes en triangle ***???)
  751.                     if (iPoints == 2)
  752.                     {
  753.                         vTrace("Deux points sélectionnés -> création arête");
  754.  
  755.                         if (-1 == iFindEdge(iPoint[0], iPoint[1]))
  756.                         {
  757.                             iMakeEdge(iPoint[0], iPoint[1]);
  758.                             vForce2DRefresh(XDC_MODE_COMPLET);
  759.                             vForce3DRefresh(XDC_MODE_COMPLET);
  760.                         }
  761.                         else
  762.                             vTrace("*** E0001 : L'arête existe déjà");
  763.                         break;
  764.                     }
  765.  
  766.                     // - soit il existe exactement 3 points sélectionnés et on fait un triangle avec
  767.                     //   (en supprimant les arêtes éventuelles existant entre ces 3 points) s'il n'existe pas déjà
  768.                     if (iPoints == 3)
  769.                     {
  770.                         vTrace("Trois points sélectionnés -> création facette");
  771.  
  772.                         if (-1 == iFindTriangle(iPoint[0], iPoint[1], iPoint[2]))
  773.                         {
  774.                             iMakeTriangle(iPoint[0], iPoint[1], iPoint[2], 0);
  775.                             vForce2DRefresh(XDC_MODE_COMPLET);
  776.                             vForce3DRefresh(XDC_MODE_COMPLET);
  777.                         }
  778.                         else
  779.                             vTrace("*** E0002 : Le triangle existe déjà");
  780.                         break;
  781.                     }
  782.  
  783.                     // - soit il existe exactement 0 points sélectionnés et on fait un triangle entre
  784.                     //   les 3 curseurs s'il n'existe pas déjà
  785.                     if (iPoints == 0)
  786.                     {
  787.                         vTrace("Zéro points sélectionnés -> création facette avec les 3 curseurs");
  788.                         iPoint[0] = iMakeVertex(Cursor2, XDC_ALLOWSAME),
  789.                         iPoint[1] = iMakeVertex(Cursor1, XDC_ALLOWSAME),
  790.                         iPoint[2] = iMakeVertex(Cursor3, XDC_ALLOWSAME);
  791.  
  792.                         if (-1 == iFindTriangle(iPoint[0], iPoint[1], iPoint[2]))
  793.                         {
  794.                             iMakeTriangle(iPoint[0], iPoint[1], iPoint[2], 0);
  795.                             vForce2DRefresh(XDC_MODE_COMPLET);
  796.                             vForce3DRefresh(XDC_MODE_COMPLET);
  797.                         }
  798.                         else
  799.                             vTrace("*** E0003 : Le triangle existe déjà");
  800.                         break;
  801.                     }
  802.  
  803.                     vTrace("*** E0004 : Nombre de points sélectionnés incorrect (doit être 0, 2 ou 3)");
  804.                 }
  805.                 break;
  806.  
  807.             case ID_EDITION_AJOUTER_SPHRE:
  808.             case ID_EDITION_AJOUTER_HMISPHRE:
  809.             case ID_EDITION_AJOUTER_TORE:
  810.                 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SPHERE), hWnd, bSphereDlgProc, (LPARAM) wmId);
  811.                 break;
  812.  
  813.             case ID_EDITION_AJOUTER_CYLINDRE:
  814.             case ID_EDITION_AJOUTER_TUBE:
  815.             case ID_EDITION_AJOUTER_CNE:
  816.             case ID_EDITION_AJOUTER_DISQUE:
  817.             case ID_EDITION_AJOUTER_CERCLE:
  818.                 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBDIV), hWnd, bSphereDlgProc, (LPARAM) wmId);
  819.                 break;
  820.  
  821.             case ID_EDITION_AJOUTER_BOINGBALL:
  822.                 vAddBoing(Cursor1, (fXmax - fXmin) /4.);
  823.                 goto _RedrawAll;
  824.  
  825.             case ID_EDITION_AJOUTER_CUBE:
  826.                 vAddCube(Cursor1, (fXmax - fXmin) /4.);
  827.                 goto _RedrawAll;
  828.  
  829.             case ID_EDITION_AJOUTER_PRISME:
  830.                 vAddPrism(Cursor1, (fXmax - fXmin) /4.);
  831.                 goto _RedrawAll;
  832.  
  833.             case ID_EDITION_AJOUTER_LAMPE:
  834.                 iMakeLamp(
  835.                         D3DLIGHT_POINT,
  836.                         dcvDiffuse,
  837.                         dcvSpecular,
  838.                         dcvAmbient,
  839.                         Cursor1,
  840.                         D3DVECTOR(0.f, 0.f, 0.f),
  841.                         D3DLIGHT_RANGE_MAX,
  842.                         0.f,
  843.                         0.f,
  844.                         0.1f,
  845.                         0.f,
  846.                         0.f,
  847.                         0.f);
  848.                 goto _RedrawAll;
  849. #ifndef NO3D
  850.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CUBE:
  851.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  852.                 D3DXCreateBox(lpd3dDevice,  5.f, 5.F, 5.f, D3DX_DEFAULT, &Objects[iCnt].pShape);
  853.                 bMoveD3DObj(iCnt, Cursor1);
  854.                 goto _RedrawAll;
  855.  
  856.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CYLINDRE:
  857.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  858.                 D3DXCreateCylinder(lpd3dDevice,  3.f, 3.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  859.                 bMoveD3DObj(iCnt, Cursor1);
  860.                 goto _RedrawAll;
  861.  
  862.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CNE:
  863.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  864.                 D3DXCreateCylinder(lpd3dDevice,  0.f, 4.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  865.                 bMoveD3DObj(iCnt, Cursor1);
  866.                 goto _RedrawAll;
  867.  
  868.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_DONUT:
  869.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  870.                 D3DXCreateTorus(lpd3dDevice,  3.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  871.                 bMoveD3DObj(iCnt, Cursor1);
  872.                 goto _RedrawAll;
  873.  
  874.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_POLYGONE:
  875.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  876.                 D3DXCreatePolygon(lpd3dDevice,  1.f, 20, D3DX_DEFAULT, &Objects[iCnt].pShape);
  877.                 bMoveD3DObj(iCnt, Cursor1);
  878.                 goto _RedrawAll;
  879.  
  880.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_SPHRE:
  881.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  882.                 D3DXCreateSphere(lpd3dDevice,  6.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  883.                 bMoveD3DObj(iCnt, Cursor1);
  884.                 goto _RedrawAll;
  885.  
  886.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_TEAPOT:
  887.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  888.                 D3DXCreateTeapot(lpd3dDevice,  D3DX_DEFAULT, &Objects[iCnt].pShape);
  889.                 bMoveD3DObj(iCnt, Cursor1);
  890.                 if (lParam) // Patch pour ne pas tout redessiner si on est en Timedemo
  891.                     break;
  892.                 goto _RedrawAll;
  893. #endif
  894.  
  895.             case ID_EDITION_AJOUTER_CHANEDECARACTRES:
  896.                 vAddTextOutline();
  897.                 goto _RedrawAll;
  898.  
  899.             case ID_EDITION_COLLER_CURSEURSURNOEUD:
  900.                 jCnt = -1;
  901.                 fDist = 1.0e10f;
  902.  
  903.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  904.                     if ((Vertices[iCnt].bEnabled) && (fDist > SquareMagnitude(Cursor1 - Vertices[iCnt].vPoint)))
  905.                     {
  906.                         jCnt = iCnt;
  907.                         fDist = SquareMagnitude(Cursor1 - Vertices[iCnt].vPoint);
  908.                     }
  909.  
  910.                 if (jCnt > -1)
  911.                 {
  912.                     Cursor1 = Vertices[jCnt].vPoint;
  913.                     vForce2DRefresh(XDC_MODE_PARTIEL);
  914.                 }
  915.                 else
  916.                     vTrace("*** E0012 : Aucun noeud");
  917.                 break;
  918.  
  919.             case ID_EDITION_COLLER_CURSEURSURCENTRE:
  920.                 Cursor1 = vCenter();
  921.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  922.                 break;
  923.  
  924.             case ID_EDITION_GRILLE :
  925.                 bGrid = bGrid ? FALSE : TRUE;
  926.                 vUpdateMenu();
  927.                 vForce2DRefresh(XDC_MODE_COMPLET);
  928.                 break;
  929.  
  930.             case ID_EDITION_GRIDSTEP :
  931.                 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GRIDSTEP), hWnd, bSphereDlgProc, (LPARAM) wmId);
  932.                 break;
  933.  
  934.             case ID_EDITION_COORDONNES :
  935.                 bCoords = bCoords ? FALSE : TRUE;
  936.                 vUpdateMenu();
  937.                 vForce2DRefresh(XDC_MODE_COMPLET);
  938.                 break;
  939.  
  940.             //////////////////////////////////// M E N U  O U T I L ///////////////////////////
  941.             case ID_OUTILS_AUCUN:
  942.                 cTool = XDC_TOOL_NONE;
  943.                 goto _ToolDone;
  944.  
  945.             case ID_OUTILS_SLECTEUR:
  946.                 cTool = XDC_TOOL_SELECT;
  947.                 goto _ToolDone;
  948.  
  949.             case ID_OUTILS_DSLECTEUR:
  950.                 cTool = XDC_TOOL_UNSELECT;
  951.                 goto _ToolDone;
  952.  
  953.             case ID_OUTILS_AIMANT:
  954.                 cTool = XDC_TOOL_MAGNET;
  955.                 goto _ToolDone;
  956.  
  957.             case ID_OUTILS_COURBE:
  958.                 cTool = XDC_TOOL_CURVE;
  959.                 iCurveLastVertex = -1;
  960.                 goto _ToolDone;
  961.  
  962.             case ID_OUTILS_COURBE_FINIRF:
  963.                 if (cTool == XDC_TOOL_CURVE)
  964.                 {
  965.                     // Si la courbe a au moins 2 sommets alors la refermer
  966.                     if (iCurveLastVertex != -1 && iCurveLastVertex != iCurveStartVertex)
  967.                     {
  968.                         if (-1 == iFindEdge(iCurveLastVertex, iCurveStartVertex))
  969.                         {
  970.                             iMakeEdge(iCurveLastVertex, iCurveStartVertex);
  971.                             vForce2DRefresh(XDC_MODE_COMPLET);
  972.                             iCurveLastVertex = -1;
  973.                         }
  974.                         else
  975.                             vTrace("*** E0013 : L'arête de fermeture existe déjà");
  976.                     }
  977.                     else
  978.                         vTrace("*** E0014 : La courbe ne peut être fermée, elle n'a pas au moins 2 points");
  979.                 }
  980.                 goto _ToolDone;
  981.  
  982.             case ID_OUTILS_EXTRUDEUR:
  983.                 cTool = XDC_TOOL_GRAB;
  984.                 bCloneSelection(D3DVECTOR(0.f, 0.0f, 0.f), XDC_MODE_EXTRUDE);
  985.                 vUpdateMenu();
  986.                 vForce2DRefresh(XDC_MODE_COMPLET);
  987.                 break;
  988.  
  989.             case ID_OUTILS_PINCE:
  990.                 cTool = XDC_TOOL_GRAB;
  991. _ToolDone:
  992.                 vUpdateMenu();
  993.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  994. //                vForce2DRefresh(XDC_MODE_COMPLET);
  995.                 break;
  996.  
  997.             //////////////////////////////////// M E N U  E N V I R O N N E M E N T ///////////////
  998.             case ID_OBSERVATEUR_DFINIROBSERVATEUR:
  999.                 Observer = Cursor1;
  1000.                 D3DUtil_SetViewMatrix(matView,
  1001.                       Observer, // From
  1002.                       Target,   // To
  1003.                       D3DVECTOR(0.f, 0.f, 0.f));
  1004.  
  1005.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  1006.                 goto _ModeDone;
  1007.  
  1008.             case ID_OBSERVATEUR_DFINIRVISE:
  1009.                 Target = Cursor1;
  1010.                 D3DUtil_SetViewMatrix(matView,
  1011.                       Observer, // From
  1012.                       Target,   // To
  1013.                       D3DVECTOR(0.f, 0.f, 0.f));
  1014.  
  1015.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  1016.                 goto _ModeDone;
  1017.  
  1018.             case ID_ENVIRONNEMENT_MODE_VUE3DDSACTIVE:
  1019.                 bActive = !bActive;
  1020.                 goto _ModeDone;
  1021.  
  1022.             case ID_OBSERVATEUR_MODE_POINT:
  1023.                 dFillMode = D3DFILL_POINT;
  1024.                 goto _ModeDone;
  1025.  
  1026.             case ID_OBSERVATEUR_MODE_FILDEFERF:
  1027.                 dFillMode = D3DFILL_WIREFRAME;
  1028.                 goto _ModeDone;
  1029.  
  1030.             case ID_OBSERVATEUR_MODE_FACETTES:
  1031.                 dFillMode = D3DFILL_SOLID;
  1032.                 goto _ModeDone;
  1033.  
  1034.             case ID_OBSERVATEUR_MODE_ZBUFFER:
  1035.                 dZBuf = (dZBuf == D3DZB_TRUE) ? D3DZB_FALSE : D3DZB_TRUE;
  1036.                 goto _ModeDone;
  1037.  
  1038.             case ID_ENVIRONNEMENT_MODE_LIGHTINGCOMPLET:
  1039.                 bLightFull = !bLightFull;
  1040.                 goto _ModeDone;
  1041.  
  1042.             //////////////////////////////////// M E N U  M O N D E ///////////////
  1043.             case ID_MONDE_ILLUMINATIONGLOBALE :
  1044.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_GLOBLIGHT), hWnd, bGlobLightDlgProc);
  1045.                 break;
  1046.  
  1047.             //////////////////////////////////// M E N U  D3D ///////////////
  1048.             case ID_SPCIFICITSDX7D3DIM_CHANGERLERENDERDEVICED3D: // Sur Amiga, Hints Warp3D
  1049. #ifndef _AMIGA_
  1050.                 if (S_OK != D3DEnum_UserChangeDevice(&m_pDeviceInfo))
  1051.                     break;
  1052.  
  1053.                 bReady = FALSE;
  1054.  
  1055.                 sprintf(cTitle, "%s(%s)", XDC_S_Title3D, m_pDeviceInfo->strDesc);
  1056.                 SendMessage(hWndPersp, WM_SETTEXT, 0, (LPARAM)cTitle);
  1057.  
  1058.                 if( FAILED( hrCloseD3D(FALSE) ) )
  1059.                     DestroyWindow( hWndMenu );
  1060.  
  1061.                 if( FAILED( hrInitD3D( hWndPersp, m_pDeviceInfo->pDeviceGUID) ) )
  1062.                     DestroyWindow( hWndMenu );
  1063.  
  1064.                 if (FAILED(hrInitWorld( lpd3dDevice )))
  1065.                 {
  1066.                     hrCloseD3D(TRUE);
  1067.                     DestroyWindow( hWndMenu );
  1068.                 }
  1069.  
  1070.                 // Mettre à jour les variables d'état du pipe D3D
  1071.                 vSetD3DState();
  1072.  
  1073.                 // Remettre en service les lampes
  1074.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  1075.                     if (Lampes[iCnt].bEnabled)
  1076.                         bUpdateLamp(iCnt);
  1077.  
  1078.                 bReady = TRUE;
  1079. #else
  1080.                 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HINT), hWnd, bHintDlgProc, NULL);
  1081. #endif
  1082.                 // Redessiner la scène
  1083.                 vForce3DRefresh(XDC_MODE_COMPLET);
  1084.                 break;
  1085.  
  1086.             case ID_SPCIFICITSDX7D3DIM_TRANSPARENCEALPHABLENDING:
  1087.                 bAlpha = bAlpha ? FALSE : TRUE;
  1088.                 goto _ModeDone;
  1089.  
  1090.             case ID_SPCIFICITSDX7D3DIM_ECLAIRAGESPCULAIRE:
  1091.                 bSpecular = bSpecular ? FALSE : TRUE;
  1092. _ModeDone:
  1093.                 // Mettre à jour le menu pour prendre en compte le changement de mode
  1094.                 vUpdateMenu();
  1095.                 
  1096.                 // Mettre à jour les variables d'état du pipe D3D
  1097.                 vSetD3DState();
  1098.                                 
  1099.                 // Redessiner la 3D
  1100.                 vForce3DRefresh(XDC_MODE_COMPLET);
  1101.                 break;
  1102.  
  1103.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_ANTIALIAS:
  1104.                 bAntialias = bAntialias ? FALSE:TRUE;
  1105.                 goto _ModeDone;
  1106.                 
  1107.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE:
  1108.                 dCull = D3DCULL_NONE;
  1109.                 goto _ModeDone;
  1110.  
  1111.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW:
  1112.                 dCull = D3DCULL_CW;
  1113.                 goto _ModeDone;
  1114.  
  1115.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW:
  1116.                 dCull = D3DCULL_CCW;
  1117.                 goto _ModeDone;
  1118.  
  1119.             case ID_SPCIFICITSDX7D3DIM_TIMEDEMO:
  1120. #ifndef _AMIGA_
  1121.                 // Tout effacer
  1122.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_EFFACER_TOUT, 0);
  1123.                 
  1124.                 // Recadrer la 2D
  1125.                 fXmin = -10.;                               // Espace de travail triview : X min
  1126.                 fXmax = 10.;                                // Espace de travail triview : X max
  1127.                 fYmin = -10.;                               // Espace de travail triview : Y min
  1128.                 fYmax = 10.;                                // Espace de travail triview : Y max
  1129.                 fZmin = -10.;                               // Espace de travail triview : Z min
  1130.                 fZmax = 10.;                                // Espace de travail triview : Z max
  1131.                 
  1132.                 // Repositionner les fenêtres
  1133.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_TRANSFORMER_MULTIVIEW, 0);
  1134.                 
  1135.                 // Initialiser les matrices view, proj, world
  1136.                 hrInitWorld(lpd3dDevice);
  1137.  
  1138.                 // Prépositionner l'observateur et le target
  1139.                 Target = D3DVECTOR(0.f, 0.f, 0.f);
  1140.                 Observer = D3DVECTOR(7.f, 7.f, 7.f);
  1141.  
  1142.                 // Recalculer les matrices
  1143.                 D3DUtil_SetViewMatrix(matView,
  1144.                           Observer, // From
  1145.                           Target,   // To
  1146.                           D3DVECTOR(0.f, 0.f, 0.f));
  1147.  
  1148.                 // Actualiser les matrices D3D
  1149.                 vSetD3DState();
  1150.  
  1151.                 // Ajouter 3 x 3 x 3 théière
  1152.                 {
  1153.                     int iX, iY, iZ;
  1154.                     for (iX = -3 ; iX < 4 ; iX += 3)
  1155.                         for (iY = -3 ; iY < 4 ; iY += 3)
  1156.                             for (iZ = -3 ; iZ < 4 ; iZ+= 3)
  1157.                             {
  1158.                                 Cursor1 = D3DVECTOR((float) iX, (float) iY, (float) iZ);
  1159.                                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_TEAPOT, 1);
  1160.                             }
  1161.                 }
  1162.                 
  1163.                 // Ajouter une lampe
  1164.                 Cursor1 = D3DVECTOR(8.f, 8.f, 8.f);
  1165.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_LAMPE, 0);
  1166.                 
  1167.                 dwTime = GetTickCount();
  1168.                 for (iCnt = 0 ; iCnt < 90 ; iCnt++)
  1169.                 {
  1170.                     // Repositionner l'observer
  1171.                     Observer = D3DVECTOR(   7.f * sinf(g_2_PI * (float) iCnt / 360.f),
  1172.                                             7.f * cosf(g_2_PI * (float) iCnt / 360.f),
  1173.                                             7.f * sinf(g_2_PI * (float) iCnt / 360.f));
  1174.  
  1175.                     // Recalculer les matrices
  1176.                     D3DUtil_SetViewMatrix(matView,
  1177.                               Observer, // From
  1178.                               Target,   // To
  1179.                               D3DVECTOR(0.f, 0.f, 0.f));
  1180.  
  1181.                     // Actualiser les matrices D3D
  1182.                     vSetD3DState();
  1183.  
  1184.                     // Retracer la 3D
  1185.                     vForce3DRefresh(XDC_MODE_COMPLET);
  1186.                 }
  1187.                 dwTime = GetTickCount() - dwTime;
  1188.                 
  1189.                 // Tout effacer
  1190.                 // SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_EFFACER_TOUT, 0);
  1191.  
  1192.                 vTrace("Timedemo exécutée en %d ms", dwTime);
  1193. #else
  1194.                 vDemo();
  1195. #endif
  1196.                 break;
  1197.  
  1198.             default:
  1199.                 vTrace("*** E0015 : Entrée menu non traitée dans cette version");
  1200.                // return (DefWindowProc(hWnd, uMsg, wParam, lParam));
  1201.          }
  1202.         break;
  1203. /*
  1204.     case WM_MOVE:
  1205.         break;
  1206.  
  1207.     case WM_SIZE:
  1208.         RECT rect;
  1209.  
  1210.         GetClientRect(hWndMenu, &rect);
  1211.         rect.left, rect.top, rect.right, rect.bottom,
  1212.         MoveWindow(hWndTrace, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); 
  1213.         break;
  1214.  
  1215.     case WM_GETMINMAXINFO:
  1216.         // Prevent the window from going smaller than some minimum size
  1217.         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
  1218.         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
  1219.         break;
  1220. */
  1221.     case WM_CHAR:  // Touches clavier :
  1222.             cKey = (TCHAR) wParam;
  1223.             switch(tolower(cKey))
  1224.             {
  1225. #ifdef _DEBUG
  1226.             case 'z' : // Insérer un marqueur de trace et indiquer l'état de la mémoire
  1227.                 {
  1228.                     ULONG lSFace   = hWndFace -> Width * hWndFace -> Height,       // Double buffer Face
  1229.                           lSTop    = hWndTop -> Width * hWndTop -> Height,         //    ''    ''   Top
  1230.                           lSRight  = hWndRight -> Width * hWndRight -> Height,     //    ''    ''   Right
  1231.                           lSTBuf   = max(max(lSFace, lSTop), lSRight),             // Triple buffer vues 2D
  1232.                           lSPersp  = hWndPersp -> Width * hWndPersp -> Height,     // Double buffer vue 3D
  1233.                           lSZBuf   = lSPersp,                                      // Z-Buffer vue 3D
  1234.                           lSScreen = hInst -> Width * hInst -> Height;             // Bitmap écran
  1235.  
  1236.                     vTrace("*** Mémoire disponible : %d C / %d F - VRam utilisée (hors textures) : %d",
  1237.                             AvailMem(MEMF_CHIP), AvailMem(MEMF_FAST),
  1238.                             2 * (lSFace + lSTop + lSRight + lSTBuf + lSPersp + lSZBuf + lSScreen)
  1239.                           );
  1240.                 }
  1241.                 break;
  1242. #endif
  1243.             case 4 :   // CTRL-D : Magic cookie ! Démo.
  1244.                 PostMessage(hWndMenu, WM_COMMAND, ID_SPCIFICITSDX7D3DIM_TIMEDEMO, 0);
  1245.                 break;
  1246.  
  1247.             case 13 :  // Enter : créer triangle
  1248.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_ARTEOUTRIANGLE, 0);
  1249.                 break;
  1250.  
  1251.             case 27 :  // ESC : Resizer le triview
  1252.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_TRANSFORMER_MULTIVIEW, 0);
  1253.                 break;
  1254.  
  1255.             case 127 : // DEL : effacer sélection
  1256.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_EFFACER_NOAUDSSLECTIONNS, 0);
  1257.                 break;
  1258.  
  1259.             case '<' : // Désélectionner tout
  1260.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_DSLECTIONNER_TOUT, 0);
  1261.                 break;
  1262.  
  1263.             case '>' : // Sélectionner tout
  1264.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_TOUT, 0);
  1265.                 break;
  1266.  
  1267.             case '!':
  1268.                 vCollect();
  1269.                 break;
  1270.  
  1271.             case ' ' : // Aucun outil
  1272.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_AUCUN, 0);
  1273.                 break;
  1274.  
  1275.             case 'c' : // Outil Courbes
  1276.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_COURBE, 0);
  1277.                 break;
  1278.  
  1279.             case 'f' : // Modif face
  1280.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_MODIFIER_FACETTES, 0);
  1281.                 break;
  1282.  
  1283.             case 'g' : // Outil Grabber
  1284.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_PINCE, 0);
  1285.                 break;
  1286.  
  1287.             case 'i' : // Inverser la sélection
  1288.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_INVERSERLASLECTION, 0);
  1289.                 break;
  1290.  
  1291.             case 'k' : // Sélectionner les noeuds connexes
  1292.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_NOEUDSCONNEXES, 0);
  1293.                 break;
  1294.  
  1295.             case 'l' : // Modif lampes
  1296.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_MODIFIER_LAMPES, 0);
  1297.                 break;
  1298.  
  1299.             case 'm' : // Modif matériaux
  1300.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_MODIFIER_MATRIAUX, 0);
  1301.                 break;
  1302.  
  1303.             case 'o' :  // Positionner observateur
  1304.                 PostMessage(hWndMenu, WM_COMMAND, ID_OBSERVATEUR_DFINIROBSERVATEUR, 0);
  1305.                 break;
  1306.  
  1307.             case 'p' : // Ajouter point
  1308.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_POINT, 0);
  1309.                 break;
  1310.  
  1311.             case 'q' : // Outil finir courbe
  1312.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_COURBE_FINIRF, 0);
  1313.                 break;
  1314.  
  1315.             case 'r' :  // Choisir le device de render
  1316.                 PostMessage(hWndMenu, WM_COMMAND, ID_SPCIFICITSDX7D3DIM_CHANGERLERENDERDEVICED3D, 0);
  1317.                 break;
  1318.  
  1319.             case 's' : // Outil Sélecteur
  1320.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_SLECTEUR, 0);
  1321.                 break;
  1322.  
  1323.             case 't' :  // Positionner cible
  1324.                 PostMessage(hWndMenu, WM_COMMAND, ID_OBSERVATEUR_DFINIRVISE, 0);
  1325.                 break;
  1326.  
  1327.             case 'u' : // Outil Désélecteur
  1328.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_DSLECTEUR, 0);
  1329.                 break;
  1330.  
  1331.             case 'x' : // Outil Extrudeur
  1332.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_EXTRUDEUR, 0);
  1333.                 break;
  1334.  
  1335.             default:
  1336.                 vTrace("Code touche '%c' (%d) ignoré", cKey, cKey);
  1337.                 break;
  1338.             }
  1339.         break;
  1340.  
  1341.     case WM_CLOSE:
  1342.         DestroyWindow( hWnd );
  1343.         return 0;
  1344.     
  1345.     case WM_DESTROY:
  1346.         PostQuitMessage(0);
  1347.         return 0L;
  1348.     }
  1349. #ifndef _AMIGA_
  1350.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  1351. #else
  1352.     return 0;
  1353. #endif
  1354. }
  1355.  
  1356.